home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BBS in a Box 7
/
BBS in a Box - Macintosh - Volume VII (BBS in a Box) (January 1993).iso
/
Files
/
Hyper
/
Ss-Sz
/
stripDelim.cpt
/
stripDelim.a
next >
Wrap
Text File
|
1987-11-27
|
10KB
|
385 lines
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; XFNC 1385 stripDelim (T, D, C, X)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; © 1987 Theodore S. Romano DMD
;
; If you want to see more, send me what you think it's worth:
; I would rather push keys then pick plaque — TSR
;
; 1413 Palisades Beach Rd.
; Peoples Republic of Santa Monica, CA 90401
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; processes the text in T under control of D, C, and X as described below
;
; T is the text to process.
; D is the list of delimiters
; C is a conversion control code
; X is a list of characters to remove
;
; D, C, and X are optional arguments.
; D defaults to:
; space comma tab return
;
; C defaults to empty, as does X.
;
; All occurances of any of the delimiters (D) are converted to occurances
; of the first delimiter in the list.
;
; Contiguous sequences of delimiters are converted to a single
; delimiter (the first one in the list).
;
; Leading and trailing delimiters are removed.
;
; The conversion control code (C) can be empty, in which case no
; conversion occurs, or it may begin with a conversion control code
; from the table below, followed by a colon.
;
; Any remaining characters in the conversion control code parameter
; must occur in pairs, the first being mapped onto the second.
;
; If the list of characters to remove (X) is not empty then those
; characters are deleted as they are encountered and are not
; copied to the result string.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; COMPILE:
;
; asm stripDelim.a
; link -sn Main=stripDelim -sn STDIO=stripDelim ∂
; -sn INTENV=stripDelim -rt XFCN=1385 ∂
; stripDelim.a.o -o "HD:Home"
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
INCLUDE 'Traps.a'
INCLUDE 'ToolEqu.a'
INCLUDE 'QuickEqu.a'
INCLUDE 'SysErr.a'
INCLUDE 'SysEqu.a'
INCLUDE 'HyperXCmd.a'
STRING ASIS
CASE OBJECT
EXPORT stripDelim
stripDelim PROC
;
; make room for the mapping table and save the registers we'll need
; our caller preserves registers D3-D7/A1-A5 for us
;
LINK A6,#-256 ; character mapping table
MOVEM.L D1/D2,-(SP) ; save registers
;
; check arguments
;
MOVE.L 8(A6),A1 ; XCmdBlockPtr
MOVE.L params(A1),A0 ; handle to source text
;
; make sure there is some text to process and allocate space for results
;
_GetHandleSize ; for clone to hold result
TST.L D0
BEQ done ; empty source
_NewHandle ; allocate place for result
BNE done
MOVE.L 8(A6),A1 ; XCmdBlockPtr
MOVE.L A0,returnValue(A1) ; save handle to result
;
; flesh out mapping table, map each character onto itself
;
MOVE.L #255,D0
MOVE.L A6,A0
mapFill: MOVE.B D0,-(A0)
DBRA D0,mapFill
;
; setup case and character conversions
;
noRemovals: CMP.W #3,(A1) ; have 3rd parameter ?
BLT doDelims
MOVE.L params+8(A1),A2 ; conversion list handle
MOVE.L (A2),A3
CLR.L D0
nextCode: MOVE.B (A3)+,D0
BEQ chkDelete ; empty string
CMP.B #':',D0
BEQ doMap
SUB.B #'A',D0
BGE.S @1
BRA.S nextCode
@1: CMP.B #'W'-'A',D0
BGT.S nextCode
;
; we get here if we are likely to have a conversion code
;
ADD.L D0,D0
MOVE.W base(D0),D1
JMP base(D1.W)
base: DC.W cA-base ; A -- alpha, lower case letters
DC.W @none-base ; B
DC.W @none-base ; C
DC.W cD-base ; D -- decimal, + - .
DC.W @none-base ; E
DC.W cF-base ; F -- flip (toggle state of entries)
DC.W cG-base ; G -- garbage (non printing)
DC.W @none-base ; H
DC.W @none-base ; I
DC.W @none-base ; J
DC.W @none-base ; K
DC.W cL-base ; L -- lower case (convert upper to)
DC.W cM-base ; M -- mac symbols
DC.W cN-base ; N -- numerals
DC.W @none-base ; O
DC.W cP-base ; P -- punctuation
DC.W @none-base ; Q
DC.W @none-base ; R
DC.W cS-base ; S -- symbols
DC.W cT-base ; T -- text only
DC.W cU-base ; U -- upper case (lower to upper)
DC.W cV-base ; V -- values (decimal & numerals)
DC.W cW-base ; W -- white space
@none BRA.S nextCode
;
; A (alpha) delete the lowercase letters
;
cA: MOVE.L #'z'-'a',D1 ; from a to z
LEA 'a'(A0),A2
@1: CLR.B (A2)+
DBRA D1,@1
BRA.S nextCode
;
; D (decimal) delete the . - , and + symbols from the table
;
cD: CLR.L '+'(A0)
BRA.S nextCode
;
; F (flip table) flip the table entries
;
cF: MOVE.W #255,D1
MOVE.L A6,A2
@1: MOVE.B -(A2),D0
BEQ.S @2
CLR.B (A2)
BRA.S @3
@2: MOVE.B D1,(A2)
@3: DBRA D1,@1
CLR.B (A0)
BRA nextCode
;
; G (garbage) delete the non-printing characters
;
cG: CLR.B $7F(A0) ; DEL
MOVE.L #$07-$01,D1 ; from SO to US
LEA $01(A0),A2
@1: CLR.B (A2)+
DBRA D1,@1
MOVE.L #$1F-$0E,D1 ; from SO to US
LEA $0E(A0),A2
@2: CLR.B (A2)+
DBRA D1,@2
MOVE.L #$FF-$D9,D1 ; from char D9 to FF
LEA $D9(A0),A2 ; first char to zap
@3: CLR.B (A2)+
DBRA D1,@3
BRA nextCode
;
; L (lower case) convert the uppercase letters to lowercase
;
cL: LEA 'A'(A0),A2 ; pointer to table entry for 'A'
MOVE.B #'a'-'A',D0 ; what to add from each entry
MOVE.L #25,D1 ; DBRA style count
@1: ADD.B D0,(A2)+ ; convert entry to uppercase
DBRA D1,@1 ; loop
BRA nextCode
;
; M (macintosh characters) delete the macintosh non ascii characters
;
cM: MOVE.L #$D8-$80,D1 ; from fishy A to fishy Y
LEA $80(A0),A2
@1: CLR.B (A2)+
DBRA D1,@1
BRA nextCode
;
; N (numbers) delete the digits 0 to 9
;
cN: MOVE.L #'9'-'0',D1 ; from 0 to 9
LEA '0'(A0),A2
@1: CLR.B (A2)+
DBRA D1,@1
BRA nextCode
;
; P (punctuation) delete ! " ' , . / : ; ? _
;
cP: LEA punctuation,A2 ; string with punctuation characters
MOVE.L #11,D1
@1: MOVE.B (A2)+,D0
CLR.B 0(A0,D0)
DBRA D1,@1
BRA nextCode
;
; S (symbols) delete rest of standard symbols (not P or D)
;
cS: LEA symbols,A2 ; string with symbol characters
MOVE.L #17,D1
@1: MOVE.B (A2)+,D0
CLR.B 0(A0,D0)
DBRA D1,@1
BRA nextCode
;
; T (text only) delete everything but alphanumeric and punctuation
;
cT: LEA 1(A0),A2 ; pointer to table entrys
MOVE.L #'/'-1,D1 ; dbra count
@1: CLR.B (A2)+ ; clear entry
DBRA D1,@1 ; loop
CLR.W '<'(A0) ; < =
CLR.B '>'(A0) ; >
CLR.B '^'(A0) ; ^
CLR.B '`'(A0) ; `
LEA '{'(A0),A2
MOVE.L #255-'{',D1
@2: CLR.B (A2)+
DBRA D1,@2
LEA punctuation,A2 ; string with punctuation characters
MOVE.L #11,D1
@3: MOVE.B (A2)+,D0
MOVE.B D0,0(A0,D0)
DBRA D1,@3
BRA nextCode
;
; U (upper case) convert the lower case letters to upper case
;
cU: LEA 'a'(A0),A2 ; pointer to table entry for 'a'
MOVE.L #'a'-'A',D0 ; what to subtract from each entry
MOVE.L #25,D1 ; DBRA style count
@1: SUB.B D0,(A2)+ ; convert entry to uppercase
DBRA D1,@1 ; loop
BRA nextCode
;
; V (value only) delete everything but numeric and decimal
;
cV: LEA 1(A0),A2 ; pointer to table entrys
MOVE.L #'/'-1,D1 ; dbra count
@1: CLR.B (A2)+ ; clear entry
DBRA D1,@1 ; loop
LEA ':'(A0),A2
MOVE.L #255-':',D1
@2: CLR.B (A2)+
DBRA D1,@2
MOVE.L #'+,-.','+'(A0)
BRA nextCode
;
; W (white space) delete white space characters
;
cW: MOVE.L #5,D1 ; from BS to CR
LEA 8(A0),A2
@1: CLR.B (A2)+
DBRA D1,@1
CLR.B ' '(A0)
BRA nextCode
;
; setup character mapping, the remaining characters in the
; conversion string are paired. The first should be set to change
; into the second
;
doMap: CLR.L D0
CLR.L D1
@next: MOVE.B (A3)+,D0
BEQ.S chkDelete
MOVE.B (A3)+,D1
BEQ.S chkDelete
MOVE.B D1,0(A0,D0)
BRA.S @next
;
; check for optional arguments (deletion list)
;
chkDelete: CMP.W #4,(A1) ; maximum number of arguments
BLT.S doDelims
;
; map characters to remove onto nulls
;
MOVE.L params+12(A1),A2 ; removals list
MOVE.L (A2),A3
CLR.L D0
@next MOVE.B (A3)+,D0
BEQ.S doDelims
CLR.B 0(A0,D0)
BRA.S @next
;
; now setup the list of delimiters
;
doDelims: CMP.W #2,(A1) ; have 2nd parameter ?
BLT.S defDelims
MOVE.L params+4(A1),A2 ; handle to delimiters
MOVE.L (A2),A3 ; pointer to delimiters
BRA.S setDelims
defDelims: LEA theDelims,A3
setDelims: CLR.L D1
MOVE.B (A3),D1 ; primary delimiter
CLR.L D0
@next: MOVE.B (A3)+,D0 ; next delimiter
BEQ.S setupDone
MOVE.B D1,0(A0,D0) ; map it onto first delimiter
BRA.S @next
;
; finally, we can do what we started to — filtering the source text
; D1 is the primary delimiter
; A0 is a pointer to the mapping table
;
setupDone: MOVE.L params(A1),A2 ; handle to source text
MOVE.L (A2),A3
MOVE.L D1,D2 ; save primary delimiter
MOVE.L returnValue(A1),A2 ; handle to result text
MOVE.L (A2),A1 ; pointer to space for result string
;
; processing loop; fetch the next character and map it
;
scanLoop: MOVE.B (A3)+,D0
BEQ.S atNull ; source ends
MOVE.B 0(A0,D0),D0 ; map character
BEQ.S scanLoop ; character deleted
;
; check for delimiters
;
CMP.B D2,D0 ; is recent character a delimiter
BNE.S copy ; nope, so copy it
CMP.B D1,D0 ; yes, so if the previous was also
BEQ.S scanLoop ; then skip it
;
; copy the accepted character to the result
;
copy: MOVE.B D0,(A1)+
MOVE.L D0,D1
BRA.S scanLoop
;
; done, delete any trailing delimiter and shrink wrap result
;
atNull: MOVE.L (A2),D0
CMP.L D0,A1
BEQ.S putResult
CMP.B -1(A1),D2 ; was last char a delimiter
BNE.S putResult
SUB.L #1,A1 ; yes, delete it
putResult: CLR.B (A1)+ ; append null to result
MOVE.L A1,D0
SUB.L (A2),D0 ; compute length to fix handle size
MOVE.L A2,A0
_SetHandleSize
;
; all done
;
done: MOVEM.L (SP)+,D1/D2
UNLK A6
MOVEM.L (SP)+,A0/A1 ; get return address and parameter
JMP (A0) ; return
;
theDelims DC.B $20,$2C,$0D,$09,$00,$00
punctuation DC.B '!"'',./:;?_[]'
symbols DC.B '#$%&()*<=>@^`{|}\~'
END